package org.stvd.common.utils.encode;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

/**
 * @Title: SM4Utils
 * @Description: SM4加解密工具类
 * @author houzx
 * @date 2020年7月29日
 */
@SuppressWarnings("restriction")
public class SM4Util {
    /**
     * 密钥
     */
    private String secretKey = "11HDESaAhiHHugDz"; 
    
    private String iv = "";
    
    private boolean hexString = false; 
    
    public SM4Util(){}
    
    /**
     * @Description: ECB模式加密
     * @param plainText
     * @return
     */
    public String encryptData_ECB(String plainText){
        try {
            SM4_Context ctx = new SM4_Context();
            ctx.isPadding = true;
            ctx.mode = SM4.SM4_ENCRYPT;
            
            byte[] keyBytes;
            keyBytes = secretKey.getBytes();
            SM4 sm4 = new SM4();
            sm4.sm4_setkey_enc(ctx, keyBytes);
            byte[] encrypted = sm4.sm4_crypt_ecb(ctx, plainText.getBytes("UTF-8"));
            String cipherText = new BASE64Encoder().encode(encrypted);
            if (cipherText != null && cipherText.trim().length() > 0)
            {
                Pattern p = Pattern.compile("\\s*|\t|\r|\n");
                Matcher m = p.matcher(cipherText);
                cipherText = m.replaceAll("");
            }
            return cipherText;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    
    /**
     * @Description: ECB模式解密
     * @param cipherText
     * @return
     */
    public String decryptData_ECB(String cipherText){
        try {
            SM4_Context ctx = new SM4_Context();
            ctx.isPadding = true;
            ctx.mode = SM4.SM4_DECRYPT;
            
            byte[] keyBytes;
            keyBytes = secretKey.getBytes();
            SM4 sm4 = new SM4();
            sm4.sm4_setkey_dec(ctx, keyBytes);
            byte[] decrypted = sm4.sm4_crypt_ecb(ctx, new BASE64Decoder().decodeBuffer(cipherText));
            return new String(decrypted, "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    
    /**
     * @Description: CBC模式加密
     * @param plainText
     * @return
     */
    public String encryptData_CBC(String plainText){  
        try{  
            SM4_Context ctx = new SM4_Context();  
            ctx.isPadding = true;  
            ctx.mode = SM4.SM4_ENCRYPT;  
              
            byte[] keyBytes;  
            byte[] ivBytes;  
           
            keyBytes = secretKey.getBytes();  
            ivBytes = iv.getBytes();  
              
            SM4 sm4 = new SM4();  
            sm4.sm4_setkey_enc(ctx, keyBytes);  
            byte[] encrypted = sm4.sm4_crypt_cbc(ctx, ivBytes, plainText.getBytes("UTF-8"));  
            String cipherText = new BASE64Encoder().encode(encrypted);  
            if (cipherText != null && cipherText.trim().length() > 0){  
                Pattern p = Pattern.compile("\\s*|\t|\r|\n");  
                Matcher m = p.matcher(cipherText);  
                cipherText = m.replaceAll("");  
            }  
            return cipherText;  
        } catch (Exception e) {  
            e.printStackTrace();  
            return null;  
        }  
    }  
    
    /**
     * @Description: CBC模式解密
     * @param cipherText
     * @return
     */
    public String decryptData_CBC(String cipherText){  
        try {  
            SM4_Context ctx = new SM4_Context();  
            ctx.isPadding = true;  
            ctx.mode = SM4.SM4_DECRYPT;  
              
            byte[] keyBytes;  
            byte[] ivBytes;  
            if (hexString) {  
                keyBytes = CovertUtil.hexStringToBytes(secretKey);  
                ivBytes = CovertUtil.hexStringToBytes(iv);  
            } else {  
                keyBytes = secretKey.getBytes();  
                ivBytes = iv.getBytes();  
            }  
              
            SM4 sm4 = new SM4();  
            sm4.sm4_setkey_dec(ctx, keyBytes);  
            byte[] decrypted = sm4.sm4_crypt_cbc(ctx, ivBytes, new BASE64Decoder().decodeBuffer(cipherText));  
            return new String(decrypted, "UTF-8");  
        } catch (Exception e) {  
            e.printStackTrace();
            return null;  
        }  
    }  
    
//    public static void main(String[] args) {
//        SM4Util sm4 = new SM4Util();
//        String cipherStr = sm4.encryptData_ECB("admin");
//        System.out.println(cipherStr);
//        System.out.println(sm4.decryptData_ECB(cipherStr));
//    }
}